package dao

import (
	"Gin-Server-01/com/server/common"
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"log"
	"sync"
	"time"
)

// Database连接池
var dbPool *Pool

// 数据库连接配置
var (
	//Dns = ""
	Dns                   = common.Configs.Database.Dsn
	MaxIdleConnections    = 10              //表示连接池中最大的空闲连接数
	MaxOpenConnections    = 100             //表示连接池中最大的打开连接数
	MaxConnectionLifetime = 5 * time.Minute //表示连接的最大生命周期:超过从连接池移除
	MaxIdleTime           = 1 * time.Second // 表示连接的最大空闲时间:超过关闭连接
)

// Pool用于管理连接池
type Pool struct {
	Connections []*gorm.DB
	mutex       sync.Mutex
}

// init
//
//	@Description: 初始化
func init() {

	if len(Dns) == 0 {
		log.Println("Dns为空,重新初始化...")
		Dns = "root:123456@tcp(127.0.0.1:3306)/mysql?charset=utf8&parseTime=True&loc=Local"
		//return
	}

	// 初始化连接池
	dbPool = &Pool{
		Connections: make([]*gorm.DB, 0),
	}
	// 创建指定数量的连接
	for i := 0; i < MaxIdleConnections; i++ {
		db, err := createConnection(Dns)
		if err != nil {
			log.Println(fmt.Sprintf("连接数据库失败: %v", err))
		}
		dbPool.Connections = append(dbPool.Connections, db)
	}

	// 打印连接池信息
	log.Println(fmt.Sprintf("连接池配置：最大空闲连接数：%d, 最大打开连接数：%d, 连接的最大生命周期：%s\n",
		MaxIdleConnections, MaxOpenConnections, MaxConnectionLifetime.String()))
}

// 创建数据库连接
func createConnection(dsn string) (*gorm.DB, error) {
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		return nil, err
	}

	sqlDB, err := db.DB()
	if err != nil {
		return nil, err
	}
	sqlDB.SetMaxIdleConns(MaxIdleConnections)       // 设置连接池中最大的空闲连接数
	sqlDB.SetMaxOpenConns(MaxOpenConnections)       // 设置连接池中最大的打开连接数
	sqlDB.SetConnMaxLifetime(MaxConnectionLifetime) // 设置连接的最大生命周期
	sqlDB.SetConnMaxIdleTime(MaxIdleTime)           // 设置连接的最大空闲时间

	return db, nil
}

// 获取数据库连接
func GetDB() (*gorm.DB, error) {
	dbPool.mutex.Lock()
	defer dbPool.mutex.Unlock()

	if len(dbPool.Connections) == 0 {
		// 如果连接池中没有连接，则创建新连接
		db, err := createConnection(Dns)
		if err != nil {
			return nil, err
		}
		return db, nil
	}

	// 从连接池中取出最后一个连接
	db := dbPool.Connections[len(dbPool.Connections)-1]
	dbPool.Connections = dbPool.Connections[:len(dbPool.Connections)-1]
	return db, nil
}

// 释放数据库连接
func ReleaseDB(db *gorm.DB) {
	dbPool.mutex.Lock()
	defer dbPool.mutex.Unlock()

	dbPool.Connections = append(dbPool.Connections, db)

	// 打印连接池信息
	log.Println(fmt.Sprintf("连接池当前存活连接数：%d\n", len(dbPool.Connections)))

}
